package com.system.core.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jakarta.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;

import lombok.extern.slf4j.Slf4j;

//@Service
@Slf4j
public class WebFlowLimitService {
	
	private static Map<String,RequestInfo> requests = new HashMap<String,RequestInfo>();
	
	public RequestInfo lookup(String key) {
		return requests.get(key);
	}
	public Set<String> lookup() {
		return requests.keySet();
	}
	
	public boolean limit(HttpServletRequest request) {
		String uri = request.getRequestURI();
		String ip = request.getHeader("X-Forwarded-For");
		if(StringUtils.isBlank(ip)) {
			ip = request.getRemoteHost();
		}
		String key = ip+uri;
		if(requests.containsKey(key)) {
			RequestInfo requestInfo = requests.get(key);
			long now = System.currentTimeMillis();
			
			long gap = now - requestInfo.getUpdateTime();
			if(gap <=  100) {
				log.warn("主机{}访问{}被限制了，上一次访问时间是：{}，相隔{}ms。",ip,uri,requestInfo.getUpdateTime(),gap);
				return false;
			} else {
				requestInfo.setUpdateTime(now);
				return true;
			}
		} else {
			RequestInfo requestInfo = new RequestInfo();
			requestInfo.setIp(ip);
			requestInfo.setRequestURI(uri);
			
			long now = System.currentTimeMillis();
			
			requestInfo.setAddTime(now);
			requestInfo.setUpdateTime(now);
			
			requests.put(key, requestInfo);
			return true;
		}
	}
	
	@Scheduled(cron = "0 0/1 * * * ?")
	public void check() {
		List<String> removeKeys = new ArrayList<>();
		for(String key:requests.keySet()) {
			RequestInfo requestInfo = requests.get(key);
			// 超过24小时清理出缓存
			if((System.currentTimeMillis() - requestInfo.getUpdateTime()) > (1000*60*60*24)) {
				removeKeys.add(key);
			}
		}
		for(String key:removeKeys) {
			requests.remove(key);
		}
		if(removeKeys.size() > 0) {
			log.info("[清理]一共{}个缓存超过24小时未访问，已清理。",removeKeys.size());
			log.info("-------------------------------------");
			for(String key:removeKeys) {
				log.info(key);
			}
			log.info("-------------------------------------");
		}
	}
}
